/** for File */
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

/** for FileInputStream */
import java.io.FileInputStream;

/** for FileOutputStream */
import java.io.FileOutputStream;

/** for IOException */
import java.io.IOException;

/** for InvalidClassException */
import java.io.InvalidClassException;

/** for ObjectInputStream */
import java.io.ObjectInputStream;

/** for ObjectOutputStrea */
import java.io.ObjectOutputStream;

/** for ArrayList */
import java.util.ArrayList;
import java.util.List;

/** for Map */
import java.util.Map;

/** for Random */
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/** for FileFilter */
import javax.swing.filechooser.FileFilter;

/**
 * This is a class to handle whole GUI of Space Traders
 * @version 1.0
 * @author Code Traders
 */
public class SpaceTraderMainGUI extends JPanel implements ActionListener, Model {
	
	/**
	 * serialVersionUID for the SpaceTraderMainGUI class
	 */
	private static final long serialVersionUID = -85799461036078502L;
	
	/**
	 * JFrame for the SpaceTraderMainGUI
	 */
	private JFrame frame;
	
	/**
	 * background ImageIcon
	 */
	private ImageIcon bg;
	
	/**
	 * Width and height for the JPanel
	 */
	private static final int WIDTH = 640, HEIGHT = 480;
	
	/**
	 * JButtons for the upper dock
	 */
	private final JButton homeButton, mapButton, 
	itemButton, storeButton, infoButton;

	/**
	 * JButton for the clicked button
	 */
	private JButton clickedButton;

	/**
	 * JButton for the turn button
	 */
	private final JButton turnButton;
	
	/**
	 * Current Universe
	 */
	private Universe universe;
	
	/**
	 * Current list of planets
	 */
	private List<Planet> planetList;
	
	/**
	 * Current Planet
	 */
	private Planet planet;
	
	/**
	 * Current Player
	 */
	private Player player;
	
	/**
	 * Current Ship
	 */
	private Ship ship;
	
	/**
	 * Current MainPanel
	 */
	private MainPanel mainPanel;
	
	/**
	 * Current MarketPlace
	 */
	private MarketPlace marketPlace;
	
	/**
	 * Sub-panel for the MainGUI
	 */
	private final JPanel subPanel = new JPanel();
	
	/**
	 * BottomPanel for the MainGUI
	 */
	private final BottomPanel bottomPanel = new BottomPanel();
	
	/**
	 * menu bar for the MainGUI
	 */
	private final JMenuBar menuBar;
	
	/**
	 * show appropriate this application initially.
	 * show appropriate panel about information of player
	 * set background and set image of buttons.
	 * @param arg
	 * @param loaded
	 */
	@SuppressWarnings("unchecked")
	public SpaceTraderMainGUI(String[] arg, boolean loaded) {
		
		super.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		
		bottomPanel.setMainGUI(this);
		
		if (loaded) {
			player = (Player) Singleton.INSTANCE.get("player");
			universe = (Universe) Singleton.INSTANCE.get("universe");
			planetList = (ArrayList<Planet>) Singleton.INSTANCE.get("planets");
			ship = (Ship) Singleton.INSTANCE.get("ship");
			System.out.println(((ArrayList<Planet>) 
					Singleton.INSTANCE.get("planets")).get(0).getGoods()[0].getPrice());
		} else {
			player = new Player();
			player.setName(arg[0]);
			try {
				player.setPilot(Integer.parseInt(arg[1]));
				player.setFighter(Integer.parseInt(arg[Numbers.TWO.getNumber()]));
				player.setTrader(Integer.parseInt(arg[Numbers.THREE.getNumber()]));
				player.setEngineer(Integer.parseInt(arg[Numbers.FOUR.getNumber()]));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			
			universe = new Universe();
			planetList = universe.getPlanets();
			final Random rand = new Random();
			ship = new Ship();
			ship.setCurrentPlanet(planetList.get(
					rand.nextInt(Numbers.TWENTY.getNumber())));
			
			/** Singleton **/
			Singleton.INSTANCE.put("player", player);
			Singleton.INSTANCE.put("ship", ship);
			Singleton.INSTANCE.put("universe", universe);
			Singleton.INSTANCE.put("planets", planetList);
			try {
				Singleton.INSTANCE.put("difficulty", 
						Integer.parseInt(arg[Numbers.FIVE.getNumber()]));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			/** Singleton **/
		}
		
		homeButton = new JButton("");
		homeButton.setBounds(Numbers.HUNDRED_THIRTEEN.getNumber(), 
				Numbers.FIVE.getNumber(), 
				Numbers.SIXTY.getNumber(), 
				Numbers.SIXTY.getNumber());
		homeButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/home_pressed.png")));
		homeButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/home.png")));
		homeButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/home.png")));
		homeButton.setActionCommand("home");
		homeButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), 
						Numbers.SIXTY.getNumber()));
		homeButton.setOpaque(false);
		homeButton.setContentAreaFilled(false);
		homeButton.setBorderPainted(false);
		homeButton.addActionListener(this);
		super.setLayout(null);
		super.add(homeButton);
		
		clickedButton = homeButton;
		
		mapButton = new JButton("");
		mapButton.setBounds(Numbers.HUNDRED_NINTY_SEVEN.getNumber(), 
				Numbers.FIVE.getNumber(), Numbers.SIXTY.getNumber(), 
				Numbers.SIXTY.getNumber());
		mapButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/map.png")));
		mapButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/map_pressed.png")));
		mapButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/map_pressed.png")));
		mapButton.setActionCommand("map");
		mapButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), Numbers.SIXTY.getNumber()));
		mapButton.setOpaque(false);
		mapButton.setContentAreaFilled(false);
		mapButton.setBorderPainted(false);
		mapButton.addActionListener(this);
		super.add(mapButton);
		
		itemButton = new JButton("");
		itemButton.setBounds(Numbers.TWO_HUNDRED_EIGHTY_TWO.getNumber(), 
				Numbers.FIVE.getNumber(), Numbers.SIXTY.getNumber(), 
				Numbers.SIXTY.getNumber());
		itemButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/item.png")));
		itemButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/item_pressed.png")));
		itemButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/item_pressed.png")));
		itemButton.setActionCommand("item");
		itemButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), 
						Numbers.SIXTY.getNumber()));
		itemButton.setOpaque(false);
		itemButton.setContentAreaFilled(false);
		itemButton.setBorderPainted(false);
		itemButton.addActionListener(this);
		super.add(itemButton);
		
		storeButton = new JButton("");
		storeButton.setBounds(Numbers.THREE_HUNDRED_SIXTY_EIGHT.getNumber(), 
				Numbers.FIVE.getNumber(), 
				Numbers.SIXTY.getNumber(), 
				Numbers.SIXTY.getNumber());
		storeButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/store.png")));
		storeButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/store_pressed.png")));
		storeButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/store_pressed.png")));
		storeButton.setActionCommand("store");
		storeButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), 
						Numbers.SIXTY.getNumber()));
		storeButton.setOpaque(false);
		storeButton.setContentAreaFilled(false);
		storeButton.setBorderPainted(false);
		storeButton.addActionListener(this);
		super.add(storeButton);
		
		infoButton = new JButton("");
		infoButton.setBounds(Numbers.FOUR_HUNDRED_FIFTY_TWO.getNumber(), 
				Numbers.FIVE.getNumber(), Numbers.SIXTY.getNumber(), 
				Numbers.SIXTY.getNumber());
		infoButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/info.png")));
		infoButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/info_pressed.png")));
		infoButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/info_pressed.png")));
		infoButton.setActionCommand("info");
		infoButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), Numbers.SIXTY.getNumber()));
		infoButton.setOpaque(false);
		infoButton.setContentAreaFilled(false);
		infoButton.setBorderPainted(false);
		infoButton.addActionListener(this);
		super.add(infoButton);
		
		bg = new ImageIcon(SpaceTraderMainGUI.class.getResource("/image/home_back.png"));
		
//		Icon imgIcon = new ImageIcon(SpaceTraderMainGUI.class.getResource("/image/moving_animated_alien_s.gif"));
//		homeImage = new JLabel(imgIcon);
//		homeImage.setBounds(225, 126, 189, 195);
//		add(homeImage);
		
//		lblX = new JLabel("X");
//		lblX.setFont(new Font("Lucida Grande", Font.BOLD, 20));
//		lblX.setForeground(Color.RED);
//		lblX.setBounds(451, 303, 14, 16);
//		add(lblX);
		
//		subPanel.setBounds(0, 343, 640, 137);
//		add(subPanel);
//		subPanel.setLayout(null);
//		subPanel.setOpaque(false);
		
		bottomPanel.setBounds(0, 
				Numbers.THREE_HUNDRED_FORTY_THREE.getNumber(), 
				Numbers.SIX_HUNDRED_FORTY.getNumber(), 
				Numbers.HUNDRED_THIRTY_SEVEN.getNumber());
		super.add(bottomPanel);
		bottomPanel.setLayout(null);
		bottomPanel.setOpaque(false);
		
		turnButton = new JButton("");
		turnButton.setBounds(Numbers.FOURTEEN.getNumber(), 
				Numbers.FIFTY_FIVE.getNumber(), 
				Numbers.NINTY_SEVEN.getNumber(), 
				Numbers.EIGHTY_TWO.getNumber());
		subPanel.add(turnButton);
		turnButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/turn.png")));
		turnButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/turn_pressed.png")));
		turnButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource("/image/turn_pressed.png")));
		turnButton.setPreferredSize(
				new Dimension(Numbers.SIXTY.getNumber(), Numbers.SIXTY.getNumber()));
		turnButton.setActionCommand("turn");
		turnButton.setOpaque(false);
		turnButton.setContentAreaFilled(false);
		turnButton.setBorderPainted(false);
		
		final JLabel lblNewLabel = new JLabel("Fuel: ");
		lblNewLabel.setBounds(Numbers.FIVE_HUNDRED_THIRTY_TWO.getNumber(), 
				Numbers.EIGHTY.getNumber(), 
				Numbers.HUNDRED_FORTY_NINE.getNumber(), 
				Numbers.TWENTY_NINE.getNumber());
		subPanel.add(lblNewLabel);
		lblNewLabel.setFont(
				new Font("Palatino Linotype", Font.PLAIN, Numbers.THIRTEEN.getNumber()));
		
		final JLabel lblNewLabel_1 = new JLabel("Life:");
		lblNewLabel_1.setBounds(Numbers.FIVE_HUNDRED_THIRTY_TWO.getNumber(), 
				Numbers.HUNDRED_ONE.getNumber(), 
				Numbers.HUNDRED_FIFTY.getNumber(), 
				Numbers.TWENTY_THREE.getNumber());
		subPanel.add(lblNewLabel_1);
		lblNewLabel_1.setFont(
				new Font("Palatino Linotype", Font.PLAIN, Numbers.THIRTEEN.getNumber()));
		turnButton.addActionListener(this);
//		lblX.setVisible(false);
		
//		mainPanel = new JPanel();
//		mainPanel.setBounds(0, 91, 640, 252);
//		mainPanel.setOpaque(false);
//		add(mainPanel);
		
		final HomePanel hp = new HomePanel();
		hp.update();
		this.addMainPanel(hp);
		
		menuBar = new JMenuBar();
		menuBar.setBounds(0, 0, 
				Numbers.SIX_HUNDRED_FORTY.getNumber(), 
				Numbers.TWENTY_ONE.getNumber());
		super.add(menuBar);
		
		final JMenu mnMenu = new JMenu("Menu");
		menuBar.add(mnMenu);
		
		super.addMouseMotionListener(new MouseAdapter() {

            @Override
            public void mouseMoved(MouseEvent e) {
                if (menuBar.isVisible()) {
                    try {
                    	final Robot robot = new Robot();
                        robot.keyPress(KeyEvent.VK_ESCAPE);
                    } catch (AWTException ex) {
                    	ex.printStackTrace();
                    }
                }
                menuBar.setVisible(e.getY() < Numbers.TWENTY_FIVE.getNumber());
            }
        });
		
		final JMenuItem mntmNew = new JMenuItem("New");
		mntmNew.setActionCommand("New");
		mntmNew.addActionListener(this);
		mnMenu.add(mntmNew);
		
		final JMenuItem mntmSave = new JMenuItem("Save");
		mntmSave.addActionListener(new ButtonListener("Save"));
		mnMenu.add(mntmSave);
		
		final JMenuItem mntmLoad = new JMenuItem("Load");
		mntmLoad.addActionListener(new ButtonListener("Load"));
		mnMenu.add(mntmLoad);
		
		final JMenu mnMiniGame = new JMenu("Mini Game");
		menuBar.add(mnMiniGame);
		
		final JMenuItem mntmHangman = new JMenuItem("HangMan");
		mntmHangman.addActionListener(new ButtonListener("HangMan") {
			public void actionPerformed(ActionEvent e) {
				HangmanGUI.main(null);
			}
		});
		mnMiniGame.add(mntmHangman);
		
		final JMenuItem mntmTetris = new JMenuItem("Tetris");
		mntmTetris.addActionListener(new ButtonListener("Tetris") {
			public void actionPerformed(ActionEvent e) {
				Tetris.main(null);
			}
		});
		mnMiniGame.add(mntmTetris);
		
//		bottomPanel.setPlanet(planet);
//		bottomPanel.setPlayer(player);
//		bottomPanel.setShip(ship);
		bottomPanel.updateBottomPanel("home");
 	}
	
	/**
	 * show appropriate location where the user is and show proper images.
	 * @param g
	 * 
	 */
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		bg.paintIcon(null, g, 0, 0);
		
		/*
		Color[] colors = {new Color(209,209,209), Color.BLUE,
		 new Color(125,161,177), new Color(232,214,165),
		  new Color(0,0,96), new Color(111,153,89), new Color(150,71,58),
		   new Color(249,253,228), new Color(100,92,43),
		    new Color(148,67,122), new Color(84,207,142),
		     new Color(193,24,107), new Color(87,69,69)};
		
		if (clickedButton.getActionCommand().equals("map")) {
			int n = 0;
			for (Planet p : planets) {
				g.setColor(colors[p.getResource().ordinal()]);
				g.fillOval(p.getPoint().getX()+20 + (n%15)*20,
				 p.getPoint().getY()+100 + (n%10)*20,
				  p.getWidth(), p.getHeight());
				if (p.equals(planet)) {
					lblX.setBounds(p.getPoint().getX()+20+(n%15)*20,
					 p.getPoint().getY()+100+(n%10)*20, 14, 16);
					lblX.setVisible(true);
				}
				n++;
			}
		}
		*/
	}
	
	/**
	 * Creates the main frame and makes it visible. 
	 */
	@Override
	public void show() {
		frame = new JFrame("SpaceTrader");
		final JPanel panel1 = this;
		frame.getContentPane().setLayout(new BorderLayout());
		frame.getContentPane().add(panel1, BorderLayout.NORTH);   //adds the GamePanel
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   //exit operation
		frame.pack();  //packs
		frame.setVisible(true);    //makes visible
		frame.setResizable(false);
	}

	/**
	 * ActionListener method for the buttons
	 * 
	 * @param e ActionEvent
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		
		if (e.getActionCommand().equals("New")) {
			restart();
			return;
		}
		
		JButton btn = (JButton) e.getSource();
		
		if (mainPanel != null) this.remove((JPanel) mainPanel);
		
		if (btn.getActionCommand().equals("turn")) {
			btn = homeButton;
		}
		clickedButton.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + clickedButton.getActionCommand() + ".png")));
		clickedButton.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + clickedButton.getActionCommand() + "_pressed.png")));
		clickedButton.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + clickedButton.getActionCommand() + "_pressed.png")));
		
		btn.setIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + btn.getActionCommand() + "_pressed.png")));
		btn.setPressedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + btn.getActionCommand() + ".png")));
		btn.setSelectedIcon(new ImageIcon
				(SpaceTraderMainGUI.class.getResource
						("/image/" + btn.getActionCommand() + ".png")));
		
//		bottomPanel.setPlanet(planet);
//		bottomPanel.setPlayer(player);
//		bottomPanel.setShip(ship);
		
		if (btn.getActionCommand().equals("store")) {
			marketPlace = new MarketPlace();
			final MarketPlacePanel mp = new MarketPlacePanel();
			mp.setMarketPlace(marketPlace);
			mp.setBottomPanel(bottomPanel);
			mp.update();
			this.addMainPanel(mp);
		} else if (btn.getActionCommand().equals("home")) {
			final HomePanel hp = new HomePanel();
			hp.update();
			this.addMainPanel(hp);
		} else if (btn.getActionCommand().equals("info")) {
			final InfoPanel ip = new InfoPanel();
			ip.update();
			this.addMainPanel(ip);
		} else if (btn.getActionCommand().equals("map")) {
			final MapPanel mp = new MapPanel();
			mp.setMainPanel(this);
			mp.update();
			this.addMainPanel(mp);
		} else if (btn.getActionCommand().equals("item")) {
			final ItemMarketPlace imp = new ItemMarketPlace();
			final ItemPanel ip = new ItemPanel();
			ip.setItemMarketPlace(imp);
			ip.setBottomPanel(bottomPanel);
			ip.update();
			this.addMainPanel(ip);
		}
		
		bottomPanel.updateBottomPanel(btn.getActionCommand());
		
//		lblX.setVisible(false);
		
		bg = new ImageIcon(SpaceTraderMainGUI.class.getResource
				("/image/" + btn.getActionCommand() + "_back.png"));
		repaint();
		
		clickedButton = btn;
	}
	
	/**
	 * 
	 * to add main panel
	 * @param p
	 */
	private void addMainPanel(JPanel p) {
		mainPanel = (MainPanel) p;
		((JPanel) mainPanel).setBounds(0, Numbers.NINTY_ONE.getNumber(), 
				Numbers.SIX_HUNDRED_FORTY.getNumber(), 
				Numbers.TWO_HUNDRED_FIFTY_TWO.getNumber());
		((JPanel) mainPanel).setOpaque(false);
		add((JPanel) mainPanel);
	}
	
	/**
	 * This method saves the current state of the game to a file. 
	 * 
	 * @param file The file path (file name) where the user wants to save the file 
	 * @throws IOException 
	 */
	public void save(File file) throws IOException {
		ObjectOutputStream out = null;
		try {
			out = new ObjectOutputStream(new FileOutputStream(file + ".codetraders"));
			out.writeObject(Singleton.INSTANCE.getInstance());
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
	
	/**
	 * This method loads the saved state of the game from a file. 
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * @param file The file path (file name)
	 *  where the user wants the save file to be loaded from
	 */
	@SuppressWarnings({ "unchecked" })
	public void load(File file) throws IOException, ClassNotFoundException {
		final int ind = file.getName().lastIndexOf('.') + 1;
		if (!file.getName().substring(ind).equals("codetraders")) {
			JOptionPane.showMessageDialog(null, "Wrong File Loaded");
			return;
		}
		final ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
		try {
			Singleton.INSTANCE.setInstance((Map<String, Object>) in.readObject());
		} catch (InvalidClassException e) {
			JOptionPane.showMessageDialog(null, "Wrong File Loaded");
			e.printStackTrace();
			return;
		} finally {
			in.close();
		}
	}
	
	/**
	 * This class is the ButtonListener implementing
	 *  the ActionListener for the save/load buttons.
	 * @author Code Traders
	 */
	private class ButtonListener implements ActionListener {
		
		/**
		 * Name of the button
		 */
		private final String buttonName;
		
		/**
		 * JFileChooser for the save and the load buttons
		 */
		private final JFileChooser fc;
		
		/**
		 * This is a constructor for the ButtonListener, 
		 * which takes in the file name as a String. 
		 * 
		 * @param buttonName The name of the file to be saved/loaded
		 */
		private ButtonListener(String buttonName) {
			this.buttonName = buttonName;
			fc = new JFileChooser();
			fc.addChoosableFileFilter(new CodeTradersFileFilter());
		}
		
		/**
		 * This is the main method to be performed when the ActionEvent is called, 
		 * to either save or load depending on the button that was pressed. 
		 * 
		 * @param e The ActionEvent called
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			int returnVal;
			if (this.buttonName.equals("Save")) {
				returnVal = fc.showDialog(null, "Save");
				if ( returnVal == JFileChooser.APPROVE_OPTION ) {
					try {
						save(fc.getSelectedFile());
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
				//requestFocusInWindow();
			} else {
				returnVal = fc.showDialog(null, "Load");
				if ( returnVal == JFileChooser.APPROVE_OPTION ) {
					try {
						load(fc.getSelectedFile());
					} catch (IOException e1) {
						e1.printStackTrace();
					} catch (ClassNotFoundException e1) {
						e1.printStackTrace();
					}
				}
				//requestFocusInWindow();
			}
		}
		
		/** 
		 * This is a tostring method.
		 * @return tostring.
		 */
		@Override
		public String toString() {
			return super.toString();
		}
	}
	
	/**
	 * This class is a FileFilter to filter
	 *  the allowed file extension type (*.codetraders)
	 * @author Code Traders
	 */
	private static class CodeTradersFileFilter extends FileFilter {
		
		/**
		 * This method sets up the accepted file extension for the FileChooser
		 * 
		 * @param f The file to be checked if is should be accepted
		 * @return true if it is in a .codetraders format, false otherwise
		 */
		@Override
		public boolean accept(File f) {
			if (f.isDirectory()) {
				return true;
			}
			final String name = f.getName();
			final int i = name.lastIndexOf('.');
			
			if ( i > 0 && i < name.length() - 1 ) {
				final String ext = name.substring(i + 1).toLowerCase();
				if ( ext.equals("codetraders") ) {
					return true;
				}
			}
			return false;
		}
		
		/**
		 * This method sets up the description of the format for the FileChooser
		 * 
		 * @return The description of the format (.codetraders)
		 */
		@Override
		public String getDescription() {
			return "Space Trader Save File (*.codetraders)";
		}
		
		/** 
		 * This is a tostring method.
		 * @return tostring.
		 */
		@Override
		public String toString() {
			return super.toString();
		}
	}
	
	/**
	 * This is to update the bottom panel.
	 */
	public void updateBottomPanel() {
		bottomPanel.updateBottomPanel("");
	}
	
	/**
	 * This is to update the main panel.
	 */
	public void update() {
		mainPanel.update();
	}
	
	/**
	 * This is to handle events while player is playing game.
	 */
	public void makeAnEvent() {
		final Event event = new Event();
		event.setMainPanel(this);
		event.createEvent();
	}
	
	/**
	 * to get universe
	 * @return universe
	 */
	@Override
	public Universe getUniverse() {
		return universe;
	}
	
	/**
	 * to set universe
	 * @param u
	 */
	@Override
	public void setUniverse(Universe u) {
		universe = u;
	}
	
	/**
	 * to get market place
	 * @return market place
	 */
	@Override
	public MarketPlace getMarketPlace() {
		return marketPlace;
	}

	/**
	 * to set market place
	 * @param m
	 */
	@Override
	public void setMarketPlace(MarketPlace m) {
		marketPlace = m;
	}

	/**
	 * to set the ship
	 * @param s
	 */
	@Override
	public void setShip(Ship s) {
		ship = s;
//		bottomPanel.setShip(ship);
		bottomPanel.updateBottomPanel("");
	}
	
	/**
	 * to get the ship
	 * @return ship
	 */
	@Override
	public Ship getShip() {
		return ship;
	}
	
	/**
	 * to get planets
	 * @return planet
	 */
	@Override
	public List<Planet> getPlanetList() {
		return planetList;
	}

	/**
	 * to set the planet
	 * @param planets
	 */
	@Override
	public void setPlanetList(List<Planet> planets) {
		this.planetList = planets;
	}

	/**
	 * to get the planet
	 * @return planet
	 */
	@Override
	public Planet getPlanet() {
		return planet;
	}

	/**
	 * to set the planet
	 * @param planet
	 */
	@Override
	public void setPlanet(Planet planet) {
		this.planet = planet;
	}

	/**
	 * when user clicks "store"
	 * @param al1
	 */
	@Override
	public void storeAccept(ActionListener al1) {
		storeButton.addActionListener(al1);
	}

	/**
	 * when user clicks "info"
	 * @param al2
	 */
	@Override
	public void infoAccept(ActionListener al2) {
		infoButton.addActionListener(al2);
	}

	/**
	 * when user clicks "map"
	 * @param a13
	 */
	@Override
	public void mapAccept(ActionListener a13) {
		mapButton.addActionListener(a13);
	}

	/**
	 * To restart this game
	 */
	@Override
	public void restart() {
		frame.setVisible(false);
		final SpaceTraderGUI st = new SpaceTraderGUI();
		final Main_Present mp = new Main_Present(st);
		mp.start();
		return;
	}
	
	/**
	 * This is to test singleton
	 * @return the getInstance of singleton.
	 */
	public java.util.Map<String, Object> getSingleton() {
		return Singleton.INSTANCE.getInstance();
	}
}
